package org.xukai.common.spel.spel;

import org.apache.commons.lang3.StringUtils;
import org.xukai.common.spel.AbstractKeyTranslater;
import org.xukai.common.spel.ArrayFieldConfig;
import org.xukai.common.spel.ComboDetailFiled;
import org.xukai.common.spel.ComboFieldConfig;
import org.xukai.common.spel.FieldConfig;
import org.xukai.common.spel.FieldConfigMapBuilder;
import org.xukai.common.spel.ListFieldConfig;

import java.util.List;
import java.util.Map;

/**
 * 将key值翻译成IFieldResolver能够解析的数据
 *
 * @author JackyLIU
 */
public class SpElKeyTranslater extends AbstractKeyTranslater {

    public SpElKeyTranslater() {

    }

    public SpElKeyTranslater(Map<String, FieldConfig<?>> configs) {
        setFieldConfigs(configs);
    }

    public SpElKeyTranslater(FieldConfigMapBuilder builder) {
        setFieldConfigs(builder.getFieldConfigs());
    }

    @Override
    public String translate(String key) {
        FieldConfig<?> config = getFieldConfig(key);
        if (null == config)
            return null;

        if (config instanceof ArrayFieldConfig) {
            return translateArray((ArrayFieldConfig<?>) config);
        }
        if (config instanceof ListFieldConfig) {
            return translateList((ListFieldConfig<?>) config);
        }

        if (config instanceof ComboFieldConfig) {
            return translateFieldName4Combo((ComboFieldConfig<?>) config);
        }
        return translateNormal(config);
    }

    /**
     * 解析基本类型的FieldConfig
     *
     * @param config
     * @return
     */
    private String translateNormal(FieldConfig<?> config) {
         StringBuilder sb = new StringBuilder("#").append(config.getDomainName()).append(".")
                 .append(config.getFieldName());

         if(StringUtils.isNotEmpty(config.getSubFieldName())) {
             sb.append("?:#").append(config.getDomainName()).append(".")
                     .append(config.getSubFieldName());
         }

         return sb.append("?:''").toString();
    }

    /**
     * 解析数组类型的fieldConfig
     *
     * @param config
     * @return
     */
    private String translateArray(ArrayFieldConfig<?> config) {
        StringBuilder sb = new StringBuilder("#").append(config.getDomainName()).append(".")
                .append(translateFieldName4Array(config.getDomainName(), config.getFieldName(), config.getSubFieldName()));

        return sb.toString();
    }

    private String translateList(ListFieldConfig<?> config) {
        StringBuilder sb = new StringBuilder("#").append(config.getDomainName()).append(".").
                append(translateFieldName4Array(config.getDomainName(), config.getFieldName(), config.getSubFieldName()));

        return sb.toString();
    }

    private String translateFieldName4Array(String domainName, String fieldName, String subFieldName) {
        int index = fieldName.indexOf('.');
        if (index == -1) {
            if(StringUtils.isNotEmpty(subFieldName)) {
                StringBuilder sb = new StringBuilder();
                sb.append("?:#").append(domainName).append(".").append(subFieldName);
                fieldName += sb.toString();
            }
            return fieldName;
        }

        StringBuilder sb = new StringBuilder(fieldName.substring(0, index)).append(".![")
                .append(fieldName.substring(index + 1, fieldName.length()));

        if(StringUtils.isNotEmpty(subFieldName)) {
            index = subFieldName.indexOf('.');
            sb.append("?:").append(subFieldName.substring(index + 1, subFieldName.length()));
        }
        sb.append("?:''").append("]");
        return sb.toString();
    }

    private String translateFieldName4Combo(ComboFieldConfig<?> comboFieldConfig) {
        StringBuilder sb = new StringBuilder();
        List<ComboDetailFiled<?>> comboFieldConfigs = comboFieldConfig.getComboFieldConfigs();
        int index = 0;
        for (ComboDetailFiled<?> comboDetailFiled : comboFieldConfigs) {
        	index++;
            if (comboDetailFiled.getUseAnotherDomain()) {
                sb.append("(#").append(comboDetailFiled.getAnotherDomainName()).append(".");
            }else {
                sb.append("(#").append(comboFieldConfig.getDomainName()).append(".");
            }
            sb.append(comboDetailFiled.getFieldName()).append("?:");

            if(StringUtils.isNotEmpty(comboDetailFiled.getSubFieldName())){
                if (comboDetailFiled.getUseAnotherDomain()) {
                    sb.append("#").append(comboDetailFiled.getAnotherDomainName()).append(".");
                }else {
                    sb.append("#").append(comboFieldConfig.getDomainName()).append(".");
                }
                sb.append(comboDetailFiled.getSubFieldName()).append("?:");
            }
            sb.append("'')");

            //这里要用.  否则判空 vaild
            sb.append("+");
            if(StringUtils.isNotEmpty(comboFieldConfig.getJoinString()) && index < comboFieldConfigs.size()){
            	sb.append("'").append(comboFieldConfig.getJoinString()).append("'+");
            }
        }
        return sb.substring(0, sb.length() - 1);
    }
}
